function* genC(i) {
  yield `C ${i}`
  return 'C 执行完了'
}

function* generator(i) {
  let g = yield i
  g = yield g
  return yield* genC(g)
}

const gen = generator(100)  // 生成器对象

console.log(gen.next())
console.log(gen.next(40))
console.log(gen.next(50))
console.log(gen.next())

console.log('-----------------------------------------------')

// 除了可以作为函数的中间返回语句使用，yield 关键字还可以作为函数的中间参数使用。上一次让 生成器函数暂停的 yield 关键字会接收到传给 next()方法的第一个值。这里有个地方不太好理解—— 第一次调用 next()传入的值不会被使用，因为这一次调用是为了开始执行生成器函数：

function* generatorFn(init) {
  console.log(init)
  console.log(yield)
  console.log(yield)
}

let generatorObj = generatorFn('第一次执行');
generatorObj.next();
generatorObj.next('我是第二次执行');
generatorObj.next('我是第三次执行');

console.log('-----------------------------------------------');

// 3. 产生可迭代对象 可以使用星号增强 yield 的行为，让它能够迭代一个可迭代对象，从而一次产出一个值：
function* generatorFn1() {
  for (const x of [1, 2, 3]) {
    yield x;
  }
}
// 等价于
function* generatorFn2() {
  yield* [1, 2, 3]
}

const a = generatorFn1();
const b = generatorFn2();

for (const x of a) {
  console.log(x);
}

for (const x of b) {
  console.log('迭代可迭代对象：');
  console.log(x);
}

// 使用 yield 实现递归算法
function* nTime(n) {
  if (n > 0) {
    yield* nTime(n - 1);
    yield n - 1;
  }
}

for (const x of nTime(3)) {
  console.log(x);
}
